package com.google.code.sfa.util;

import org.biojava.bio.symbol.AbstractSymbolList;
import org.biojava.bio.symbol.SymbolList;
import java.util.*;
import org.biojava.bio.symbol.Symbol;
import org.biojava.bio.symbol.Alphabet;
import org.biojava.bio.seq.DNATools;
import org.biojava.bio.symbol.IllegalSymbolException;

public class MySymbolList extends AbstractSymbolList {
    
    List<Set> _positiveList, _negativeList;

    public MySymbolList( SymbolList seed) {
	_positiveList = new ArrayList<Set>();
	_negativeList = new ArrayList<Set>();

	set( 1, seed);
    }

    public void set( int first, SymbolList seq) {
	int offset = first - _negativeList.size();
	int real;
	if( offset <= 0) {
	    for( int i = seq.length(); i > 0; i--) {
		real = i + first - 1;
		// every time you add one to zero everything gets shifted right
		if( real < 1) {
		    real = 0;
		}
		setSymbol( real, seq.symbolAt(i) );
	    }
	} else {
	    for( int i = 1; i <= seq.length(); i++) {
		real = i + first - 1;
		setSymbol( real, seq.symbolAt(i) );
	    }
	}
    }

    public void setSymbol( int index, Symbol s) {
	int offset = index - _negativeList.size();
	if( offset <= 0) {
	    offset = -1 * offset;
	    if( offset > _negativeList.size() ) {
		throw new IndexOutOfBoundsException( "Adding a contig with no overlap");
	    } else if( offset == _negativeList.size() ) {
		Set set = new DNASymbolSet();
		set.add( s);
		_negativeList.add( set);
	    } else {
		_negativeList.get(offset).add( s);
	    }
	} else {
	    offset = offset - 1;
	    if( offset > _positiveList.size() ) {
		throw new IndexOutOfBoundsException( "Adding a contig with no overlap");
	    } else if( offset == _positiveList.size() ) {
		Set set = new DNASymbolSet();
		set.add( s);
		_positiveList.add( set);
	    } else {
		_positiveList.get(offset).add( s);
	    }
	}
    }

    public Alphabet getAlphabet() {
	return DNATools.getDNA();
    }
    public int length() {
	return _positiveList.size() + _negativeList.size();
    }
    public Symbol symbolAt(int index) {
	int offset = index - _negativeList.size();
	try {
	    Set s;
	    if( offset <= 0) {
		s = _negativeList.get( offset * -1);
	    } else {
		s = _positiveList.get( offset - 1);
	    }
	    if( s.size() > 1) {
		s = new HashSet( s);
	    }
	    return getAlphabet().getAmbiguity( s);
	} catch( IllegalSymbolException e) {
	    return DNATools.n();
	}
    }

}

